import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Between, FindOptionsWhere, Like, Repository } from 'typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import {
  IPaginationOptions,
  paginate,
  Pagination
} from 'nestjs-typeorm-paginate';
import { Role } from '../role/entities/role.entity';
import { UpdatePasswordUserDto } from './dto/update-password-user.dto';
import { BusinessException } from '@/common';
import { isNotEmptyObject } from 'class-validator';
import { Attachement } from '../attachement/entities/attachement.entity';
import { AttachementService } from '../attachement/attachement.service';
import { userQueryVo } from '@/common/interface';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly attachementService: AttachementService
  ) {}

  async create(createUserDto: CreateUserDto) {
    // 查询人员是否已存在
    const hasUser = await this.findOneByUsername(createUserDto.username);
    if (hasUser) {
      throw new BadRequestException({
        code: 400,
        message: '用户名已存在'
      });
    }

    // 创建user实例
    const user = new User();
    ['username', 'password', 'realname', 'email', 'phone'].forEach((v) => {
      user[v] = createUserDto[v] ?? null;
    });

    // 关联附件-头像
    if (isNotEmptyObject(createUserDto.attachement)) {
      const { name, filename, url, size, mimetype } = createUserDto.attachement;
      if (!url) {
        return;
      }
      const attachement = new Attachement();
      attachement.name = name;
      attachement.filename = filename;
      attachement.url = url;
      attachement.size = size;
      attachement.mimetype = mimetype;
      user.avatar = attachement;
    }

    // 关联角色
    const roles = createUserDto.roles.map((item) => {
      const role = new Role();
      role.id = item.id;
      return role;
    });
    user.roles = roles;

    this.userRepository.save(user);
  }

  findOneByUsername(username: string) {
    return this.userRepository.findOne({
      where: { username },
      select: ['id', 'username', 'password', 'createdAt', 'isAdmin'], // 选择查询返回的列
      relations: ['roles','avatar']
    });
  }

  findAll(
    option: IPaginationOptions,
    userQuery: userQueryVo
  ): Promise<Pagination<User>> {
    const { username, queryDate } = userQuery;

    const where: FindOptionsWhere<User> = {};

    if (username) {
      where.username = Like(`%${username}%`);
    }

    if (queryDate?.length > 0) {
      where.createdAt = Between(queryDate[0], queryDate[1]);
    }

    return paginate(this.userRepository, option, {
      where,
      relations: ['roles', 'avatar']
    });
  }

  async findOne(id: number) {
    const result = await this.userRepository.findOne({
      where: { id },
      relations: ['roles', 'avatar']
    });

    // 删除 Password 属性

    // if (result.hasOwnProperty('password')) {
    //   delete result.password;
    // }

    return result;
  }

  async update(updateUserDto: UpdateUserDto, userId: number) {
    // 创建user实例
    const user = new User();
    ['id', 'username', 'password', 'realname', 'email', 'phone'].forEach(
      (v) => {
        if (updateUserDto[v]) {
          user[v] = updateUserDto[v];
        }
      }
    );

    // 人员修改不修改头像
    // 关联角色
    const roles = updateUserDto.roles.map((item) => {
      const role = new Role();
      role.id = item.id;
      return role;
    });
    user.roles = roles;

    this.userRepository.save(user);
  }

  async remove(id: number) {
    const user = await this.findOne(id);
    // 删除关联的附件
    await this.attachementService.removeFile(id);
    return this.userRepository.remove(user);
  }

  async updatePassword(updatePasswordUserDto: UpdatePasswordUserDto) {
    const { id, password, newPassword } = updatePasswordUserDto;
    const user = await this.findOne(id);
    if (!user) {
      throw new BusinessException({ code: 400, message: '用户不存在' });
    }
    // 验证旧密码
    if (password !== user.password) {
      throw new BusinessException({ code: 400, message: '密码不正确' });
    }
    user.password = newPassword;
    return this.userRepository.update(id, user);
  }

  async resetPassword(id: number) {
    const user = await this.findOne(id);
    user.password = '123456';
    return this.userRepository.update(id, user);
  }

  async setAdmin(id: number, isAdmin: number) {
    const user = await this.findOne(id);
    user.isAdmin = isAdmin;
    return this.userRepository.update(id, user);
  }

  // 供其他服务调用更新user实体
  saveUser(user: User) {
    return this.userRepository.save(user);
  }

  // 更新用户头像
  async updateAvatar(id: number, file: Attachement) {
    const user = await this.findOne(id);

    // 关联附件-头像
    if (isNotEmptyObject(file)) {
      const { name, filename, url, size, mimetype } = file
      if (!url) {
        return;
      }
      const attachement = new Attachement();
      attachement.name = name;
      attachement.filename = filename;
      attachement.url = url;
      attachement.size = size;
      attachement.mimetype = mimetype;
      user.avatar = attachement;
    }

    this.userRepository.save(user);
  }
}
